package com.sfx.concurrent.demo.线程基础.线程的创建;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.atomic.AtomicInteger;

import static com.sfx.concurrent.demo.线程基础.线程的创建.CreateDemo.getCurThreadName;

@Slf4j(topic = "c.SalesDemo")
public class SalesDemo {
    public static final int MAX_AMOUNT = 5; //商品数量

    //通过继承Thread类实现多线程能更好地做到多个线程并发地
    //完成各自的任务，访问各自的数据资源
    //商店商品类（销售线程类），一个商品一个销售线程，每个线程异步销售4次
    static class StoreGoods extends Thread {
        StoreGoods(String name) {
            super(name);
        }

        private int goodsAmount = MAX_AMOUNT;

        public void run() {
            for (int i = 0; i <= MAX_AMOUNT; i++) {
                if (this.goodsAmount > 0) {
                    log.info(getCurThreadName() + " 卖出一件，还剩："
                            + (--goodsAmount));
                    sleepMilliSeconds(10);
                }
            }
            log.info(getCurThreadName() + " 运行结束.");
        }
    }

    //商场商品类（target销售线程的目标类），一个商品最多销售4次，可以多人销售
    static class MallGoods implements Runnable {
        //多人销售可能导致数据出错，使用原子数据类型保障数据安全
        private AtomicInteger goodsAmount = new AtomicInteger(MAX_AMOUNT);

        public void run() {
            for (int i = 0; i <= MAX_AMOUNT; i++) {
                if (this.goodsAmount.get() > 0) {
                    log.info(getCurThreadName() + " 卖出一件，还剩："
                            + (goodsAmount.decrementAndGet()));
                    sleepMilliSeconds(10);
                }
            }
            log.info(getCurThreadName() + " 运行结束.");
        }
    }

    public static void sleepMilliSeconds(int seconds) {
        try {
            Thread.sleep(seconds);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String args[]) throws InterruptedException {
        log.info("商店版本的销售");
        for (int i = 1; i <= 2; i++) {
            Thread thread = null;
            thread = new StoreGoods("店员-" + i);
            thread.start();
        }
        Thread.sleep(1000);

        log.info("商场版本的销售");
        MallGoods mallGoods = new MallGoods();
        for (int i = 1; i <= 2; i++) {
            Thread thread = null;
            thread = new Thread(mallGoods, "商场销售员-" + i);
            thread.start();
        }
        log.info(getCurThreadName() + " 运行结束.");
    }
}